home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
-
- #import "GameView.h"
- #import "Animator.h" // timer controller
- #import "GameBrain.h" // Partner in crime
- #import "PreferencesBrain.h" // for user's preferences
- #import <appkit/color.h> // Colors
- #import <appkit/Application.h> // event stuff, misc.
- #import <appkit/Speaker.h> // for dragging
- #import <appkit/Listener.h> // for dragging
- #import <appkit/NXImage.h> // for tiff rendering
- #import <appkit/OpenPanel.h> // for setting backgrounds
- #import <appkit/publicWraps.h> // used to set up dragging (get windownum)
- #import <appkit/nextstd.h> // for NX_FREE, etc.
- #import <dpsclient/psops.h> // PSsetgray()
- #import <dpsclient/wraps.h> // PScompositerect()
- #import <libc.h> // for random(), etc.
- #import <math.h> // for floor(), etc.
- #import <stdio.h> // for standard C file operations
-
-
- @implementation GameView
-
- - initFrame:(const NXRect *)frm // designated initializer for a view
- {
- char *slashPos;
-
- [super initFrame:frm];
-
- // seed random number generator
-
- srandom(time(0));
-
- // some defaults
-
- demoMode = NO;
- grayBorder = YES;
-
- // get .app wrapper pathname and then load .snd files
-
- appPath = (char *)malloc(256);
- strcpy(appPath, NXArgv[0]);
- if (slashPos = strrchr(appPath, '/')) {
- sprintf(slashPos+1, "\0");
- } else {
- strcpy(appPath, "./");
- }
-
- // initialize game variables
- state = GAMEOVER;
- demoWait = 0;
- doingBorder = NO;
- grayBorder = YES;
-
- backColor = NXConvertRGBToColor(0.333, 0.333, 0.333); // dark gray default
- backIsColor = YES; // default bg is dark gray...
- [self allocateGState];
- return self;
- }
-
- - loadPix
- {
- const char *tmpStr;
- char *okStr; float r, g, b;
-
- // set background
- okStr = malloc(8);
- tmpStr = NXGetDefaultValue([NXApp appName], "BackColor");
- if (tmpStr) {
- backIsColor = NO;
- sscanf(tmpStr, "%s %f %f %f", &okStr[0], &r, &g, &b);
- backColor = NXConvertRGBToColor(r, g, b);
- if (okStr[0] == 'Y') {
- backIsColor = YES;
- }
- }
- free(okStr);
-
- if (!backIsColor)
- [self setBackgroundFile:
- NXGetDefaultValue([NXApp appName], "BackGround")
- andRemember:NO];
-
- return self;
- }
-
- - animate:sender
- { // method to start the animation - called by appDidInit
-
- // set up Animator: (autoUpdate) this handles moving viruses and
- // makes sure the columns fall when they should. The animator is
- // an object that handles timed entries "smartly".
- animator = [[Animator alloc] initChronon:[self speedTime]
- adaptation:0.0 target:self
- action:@selector(autoUpdate:) autoStart:YES eventMask:0];
-
- return self;
- }
-
- - (BOOL)demoMode // if last game was demo
- { return demoMode; }
-
- - (float)speedTime // returns time between animation frames
- { return GRANULARITY; // return delay between clock ticks
- } // 0.05 is about as fast as should be used.
-
- - (int)gameState // tell caller our state... if in demo, game is over
- { if (demoMode) return GAMEOVER; return state; }
-
- - autoUpdate:sender // called by timed entry to update screen periodically
- { // ALL animation is controlled from here!!!
- cycles++;
- // you would do updates to various screen objects and
- // then do a [self updateSelf:&bounds :1];
- return self;
- }
-
- - updateSelf:(NXRect *)rects :(int)rectCount // redraws the screen.
- { // it redraws only what has changed since last redraw.
- NXPing();
- return self;
- }
-
- - mouseDown:(NXEvent *)event // handle mouseDown events.
- {
- [controller pauseGame:self]; // pause/unpause game
- return self;
- }
-
- - (BOOL)acceptsFirstMouse // let us grab activating mousedowns
- { // 1st click is to become 1st responder, NOT pause/unpause
- return NO;
- }
-
- - setKey:(int)keyIndex val:(char)keyVal // change key we respond to
- {
- keys[keyIndex] = keyVal;
- return self;
- }
-
- - pause:sender // set pause status.
- {
- paused = YES;
- return self;
- }
-
- - unpause:sender // remove paused status
- {
- paused = NO;
- return self;
- }
-
- - (BOOL)isPaused // tell caller is we're paused
- { return paused; }
-
- - keyDown:(NXEvent *)myevent // handle keyDown events.
- {
- if (myevent->data.key.charSet == NX_ASCIISET &&
- (myevent->flags&(NX_CONTROLMASK|NX_ALTERNATEMASK|NX_COMMANDMASK)) == 0)
- {
- if (myevent->data.key.charCode == 'p') { // allow pause
- if (paused) [controller unpause];
- else [controller pause];
- } else if (paused) { // any keyDown unpauses game (except 'p').
- [controller unpause];
- } else if (myevent->data.key.charCode == 'n') { // allow new game
- if (([self gameState] != GAMEOVER) && ([preferences alert])) {
- // if game in progress, alert user about this
- if (NXRunAlertPanel(NULL,
- "Do you want to throw away the current game?",
- "You betcha!", "Um, no.", NULL) != NX_ALERTDEFAULT) {
- return self; // allow "graceful escape"
- }
- }
- if ([self gameState] != GAMEOVER) {
- [controller gameOver]; // Force Game Over.
- state = GAMEOVER;
- }
- [controller startNewGame:self]; // re-start the game
- }
- } else return [super keyDown:myevent];
- return self;
- }
-
- - (BOOL)acceptsFirstResponder // to grab keyboard events
- { return YES; }
-
- - getPreferences
- {
- soundEffects = [preferences effects];
- music = [preferences music];
- return self;
- }
-
-
- - soundOn // turn on sound effects
- {
- soundEffects = YES;
- return self;
- }
-
- - soundOff // turn off sound effects
- {
- soundEffects = NO;
- return self;
- }
-
- - musicOn // turn on music
- {
- music = YES;
- return self;
- }
-
- - musicOff // turn off music
- {
- music = NO;
- return self;
- }
-
- - free // get rid of support objects
- {
- [animator free];
- [self unregisterWindow];
- return [super free];
- }
-
- - setUpScreen
- {
- if ((demoMode)||(doingBorder)) [self display];
-
- return self;
- }
-
- - changeBorder:(BOOL)borderOn
- { // move view about in the window & do sizing
- // NOT USED in PacMan...it's best if you don't use it, in fact.
- NXRect wFrame;
-
- if (borderOn == grayBorder) return self;
-
- if (borderOn) {
- [window getFrame:&wFrame];
- NXInsetRect(&wFrame, -BEZELSIZE, -BEZELSIZE);
- [self moveBy:BEZELSIZE :BEZELSIZE];
- [window placeWindowAndDisplay:&wFrame];
- } else {
- [window getFrame:&wFrame];
- NXInsetRect(&wFrame, BEZELSIZE, BEZELSIZE);
- [self moveBy:-BEZELSIZE :-BEZELSIZE];
- [window placeWindowAndDisplay:&wFrame];
- }
- grayBorder = borderOn;
- return self;
- }
-
- - restartGame
- {
- return self;
- }
-
-
- //// Background handling methods stolen from BreakApp:
- //
-
- - setBackgroundFile:(const char *)fileName andRemember:(BOOL)remember
- // This methods allows changing the file used to paint the background of the
- // playing field. Set fileName to NULL to revert to the default. Set
- // remember to YES if you wish the write the value out in the defaults.
- {
- [backGround free];
-
- backGround = [[NXImage allocFromZone:[self zone]] initSize:&bounds.size];
- if (fileName) {
- [backGround useFromFile:fileName];
- if (remember) {
- NXWriteDefault ([NXApp appName], "BackGround", fileName);
- }
- } else {
- [backGround useFromSection:"BackGround.eps"];
- if (remember) {
- NXRemoveDefault ([NXApp appName], "BackGround");
- }
- }
- backIsColor = NO;
- [self writeColor];
- [backGround setBackgroundColor:NX_COLORWHITE];
- [backGround setScalable:YES];
- [self display];
-
- return self;
- }
-
-
- // The following two methods allow changing the background image from
- // menu items or buttons.
-
- - changeBackground:sender
- {
- const char *const types[] = {"tiff", "eps", NULL};
-
- if ([[OpenPanel new] runModalForTypes:types]) {
- [self setBackgroundFile:[[OpenPanel new] filename] andRemember:YES];
- [self display];
- }
-
- return self;
- }
-
- - revertBackground:sender
- {
- [self setBackgroundFile:NULL andRemember:YES];
- [self display];
- return self;
- }
-
- - back1:sender
- {
- char *tempStr;
-
- tempStr = malloc(256);
- sprintf(tempStr, "%sBack1.tiff", appPath);
- [self setBackgroundFile:tempStr andRemember:YES];
- free(tempStr);
- [self display];
- return self;
- }
-
- - back2:sender
- {
- char *tempStr;
-
- tempStr = malloc(256);
- sprintf(tempStr, "%sBack2.tiff", appPath);
- [self setBackgroundFile:tempStr andRemember:YES];
- free(tempStr);
- [self display];
- return self;
- }
-
- - back3:sender
- {
- char *tempStr;
-
- tempStr = malloc(256);
- sprintf(tempStr, "%sBack3.tiff", appPath);
- [self setBackgroundFile:tempStr andRemember:YES];
- free(tempStr);
- [self display];
- return self;
- }
-
- - drawBackground:(NXRect *)rect
- // drawBackground: just draws the specified piece of the background by
- // compositing from the background image.
- {
- NXRect tmpRect = *rect;
-
- if (backIsColor) {
- NXSetColor(backColor);
- NXRectFill(rect);
- return self;
- }
-
- NX_X(&tmpRect) = floor(NX_X(&tmpRect));
- NX_Y(&tmpRect) = floor(NX_Y(&tmpRect));
- if (NXDrawingStatus == NX_DRAWING) {
- PSsetgray (NX_WHITE);
- PScompositerect (NX_X(&tmpRect), NX_Y(&tmpRect),
- NX_WIDTH(&tmpRect), NX_HEIGHT(&tmpRect), NX_SOVER);
- }
- [backGround composite:NX_SOVER fromRect:&tmpRect toPoint:&tmpRect.origin];
- return self;
- }
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- [super sizeTo:width :height];
- [backGround setSize:&bounds.size];
- return self;
- }
-
-
- // deal with drag and drop colors:
- - acceptColor:(NXColor)color atPoint:(NXPoint *)aPoint
- {
- backIsColor = YES;
- backColor = color;
- [[self writeColor] update];
- return self;
- }
-
- - writeColor
- {
- char def[256];
- char bic[16] = "YES";
- float r, g, b;
-
- if (!backIsColor) sprintf(bic, "NO");
-
- NXConvertColorToRGB(backColor, &r, &g, &b);
-
- sprintf(def, "%s %f %f %f", bic, r, g, b);
- NXWriteDefault ([NXApp appName], "BackColor", def);
- return self;
- }
-
-
- // The drag and drop .tiff/.eps is borrowed and modified from the
- // Adobe example NX_ImportAdv which demonstrates tiff/eps handling.
- // I've taken the code chunk for drag and drop and modified it to
- // work for setting backgrounds.
-
-
- /*
- * Registers the document window with the Workspace Manager so that when the
- * user picks up an icon in the Workspace and drags it over our document window
- * and lets go, iconEntered:... and iconReleasedAt::ok: messages will be
- * sent to the DrawDocument from the Workspace Manager. Allows the user to
- * drag PostScript and TIFF files into the document.
- */
- - registerWindow
- {
- unsigned int windowNum;
- id speaker = [NXApp appSpeaker];
-
- listenerId = [Listener new];
- [listenerId setDelegate:self];
- [listenerId usePrivatePort];
- [listenerId addPort];
-
- NXConvertWinNumToGlobal([window windowNum], &windowNum);
- [speaker setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)];
- [speaker registerWindow:windowNum toPort:[listenerId listenPort]];
-
- return self;
- }
-
- /* Undoes what registerWindow does. */
- - unregisterWindow
- {
- unsigned int windowNum;
- id speaker = [NXApp appSpeaker];
-
- if (listenerId)
- {
- [speaker setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)];
- NXConvertWinNumToGlobal([window windowNum], &windowNum);
- [speaker unregisterWindow:windowNum];
- [listenerId free];
- }
-
- return self;
- }
-
- /*
- * Called whenever an icon is dragged from the Workspace over the document
- * window. At this point, all that is done is to salt away the list of files
- * represented by the icon. All the real work is done in iconReleasedAt::ok:.
- */
- - (int)iconEntered:(int)windowNum at:(double)x :(double)y
- iconWindow:(int)iconWindowNum iconX:(double)iconX iconY:(double)iconY
- iconWidth:(double)iconWidth iconHeight:(double)iconHeight
- pathList:(char *)pathList
- {
- if (!iconPathList || strcmp(iconPathList, pathList))
- { // if new list of files, copy it in for us to look at later
- NX_FREE(iconPathList);
- NX_MALLOC(iconPathList, char, strlen(pathList)+1);
- strcpy(iconPathList, pathList);
- }
- return 0;
- }
-
- /*
- * Goes through the list of files associated with the icon dragged
- * from the Workspace and checks if any of them are PostScript or TIFF.
- * If any are, then the GraphicView is asked to load those in as objects.
- * Very important: an NX_DURING handler is required around all the processing
- * of this method since an uncaught raised error will cause this method not
- * to return and thus hang the Workspace Manager for a while.
- */
- - (int)iconReleasedAt:(double)x :(double)y ok:(int *)flag
- {
- volatile int foundOne = NO;
- char *file, *tab, *extension;
-
- NX_DURING
- file = iconPathList;
- tab = strchr(file, '\t');
- if (tab)
- *tab = '\0';
- extension = strrchr(file, '.');
- if (extension) {
- if (!strcmp(extension, ".eps") || !strcmp(extension, ".tiff")) {
- [self setBackgroundFile:file andRemember:YES];
- foundOne = YES;
- }
- }
- if (foundOne) {
- [NXApp activateSelf:YES];
- [window makeKeyAndOrderFront:self];
- }
- NX_HANDLER
- NX_ENDHANDLER
-
- *flag = foundOne;
-
- return 0;
- }
-
- @end
-